package view.table.square;

import java.awt.Component;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import model.Square;
import model.validation.ShapeValidationException;
import view.ControllerEventParser;
import view.IView;
import view.table.CellValueChangeEvent;
import view.table.CellValueChangeListener;
import appmodel.ControllerEvent;
import controller.Controller;

public class SquareView implements IView {

	private Controller controller;
	private Component swingView;
	private SquareTableModel squareTableModel;
	private JTable table;

	public SquareView(Controller controller) {
		super();
		this.controller = controller;
		squareTableModel = new SquareTableModel(new ArrayList<Square>(controller.getSquares()));
		table = new JTable(squareTableModel);
		swingView = new JScrollPane(table);
		createSaveProvider(squareTableModel, swingView);
		controller.registerView(this);
	}

	private void createSaveProvider(final SquareTableModel squareModel, final Component component) {
		squareModel.setSaveProvider(new CellValueChangeListener() {

			@Override
			public void onChange(CellValueChangeEvent e) {
				Integer newValue = (Integer) e.getValueToChange();
				Square square = (Square) e.getCurrentObject();
				int oldX = square.getX();
				int oldY = square.getY();
				int oldA = square.getA();
				switch (e.getChangeAtColumn()) {
				case 0:
					square.setX(newValue);
					break;
				case 1:
					square.setY(newValue);
					break;
				case 2:
					square.setA(newValue);
					break;
				default:
					break;
				}
				try {
					controller.editShape(square);
				} catch (ShapeValidationException e2) {
					JOptionPane.showMessageDialog(component, "Invalid arguments");
					square.setY(oldY);
					square.setX(oldX);
					square.setA(oldA);
				}
			}
		});
	}

	@Override
	public void onControllerEvent(ControllerEvent event) {
		ControllerEventParser parser = new ControllerEventParser(event){
			public void addShape(Square s) {
				squareTableModel.addSquare(s);
			};
			
			public void removeShape(Square s) {
				squareTableModel.removeSquare(s);
			};
			public void refresh() {
				squareTableModel.setSquares(new LinkedList<Square>(controller.getSquares()));
			}
		};
		parser.processEvent();
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				table.updateUI();
			}
		});
	}

	public Component getSwingView() {
		return swingView;
	}

}
